/*
 * Copyright (c) 2025 Industrial Software Feature Database
 */
package com.comac.ins.isfd.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.comac.ins.common.core.exception.base.BaseException;
import com.comac.ins.common.core.service.UserService;
import com.comac.ins.common.core.utils.MapstructUtils;
import com.comac.ins.common.core.utils.StringUtils;
import com.comac.ins.common.mybatis.core.page.PageQuery;
import com.comac.ins.common.mybatis.core.page.TableDataInfo;
import com.comac.ins.isfd.constant.enums.IsfdImportMethodEnum;
import com.comac.ins.isfd.domain.IsfdSceneMapStepModelRef;
import com.comac.ins.isfd.domain.bo.IsfdDatabaseDataImportRecordBo;
import com.comac.ins.isfd.domain.bo.IsfdSceneMapStepModelRefBo;
import com.comac.ins.isfd.domain.vo.*;
import com.comac.ins.isfd.domain.vo.blood.BloodRelationshipInnerV2Vo;
import com.comac.ins.isfd.domain.vo.blood.BloodRelationshipOuterV2Vo;
import com.comac.ins.isfd.mapper.IsfdSceneMapStepModelRefMapper;
import com.comac.ins.isfd.mapper.IsfdServerManagementMapper;
import com.comac.ins.isfd.service.IIsfdDatabaseDataImportRecordService;
import com.comac.ins.isfd.service.IIsfdDatabaseModelConfigService;
import com.comac.ins.isfd.service.IIsfdSceneMapStepModelRefService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统地图步骤-模型关联Service业务层处理
 *
 * @author hxloongs
 * @date 2025-03-03
 */
@RequiredArgsConstructor
@Service
public class IsfdSceneMapStepModelRefServiceImpl implements IIsfdSceneMapStepModelRefService {

    @Autowired
    private IsfdSceneMapStepModelRefMapper baseMapper;

    @Autowired
    private IIsfdDatabaseModelConfigService iIsfdDatabaseModelConfigService;

    @Autowired
    private IIsfdDatabaseDataImportRecordService iIsfdDatabaseDataImportRecordService;

    @Autowired
    private UserService userService;

    @Autowired
    private IsfdServerManagementMapper isfdServerManagementMapper;

    @Override
    public IsfdSceneMapStepModelRefVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }


    @Override
    public TableDataInfo<IsfdSceneMapStepModelRefVo> queryPageList(IsfdSceneMapStepModelRefBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<IsfdSceneMapStepModelRef> lqw = buildQueryWrapper(bo);
        Page<IsfdSceneMapStepModelRefVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }


    @Override
    public List<IsfdSceneMapStepModelRefVo> queryList(IsfdSceneMapStepModelRefBo bo) {
        LambdaQueryWrapper<IsfdSceneMapStepModelRef> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<IsfdSceneMapStepModelRef> buildQueryWrapper(IsfdSceneMapStepModelRefBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<IsfdSceneMapStepModelRef> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getMapStepId() != null, IsfdSceneMapStepModelRef::getMapStepId, bo.getMapStepId());
        lqw.eq(bo.getDatabaseTypeId() != null, IsfdSceneMapStepModelRef::getDatabaseTypeId, bo.getDatabaseTypeId());
        lqw.eq(bo.getModelId() != null, IsfdSceneMapStepModelRef::getModelId, bo.getModelId());
        return lqw;
    }

    @Override
    @Transactional
    public Boolean insertByBo(IsfdSceneMapStepModelRefBo bo) {
        IsfdDatabaseModelConfigVo modelConfigVo = iIsfdDatabaseModelConfigService.queryByIdReturnSimpleVo(bo.getModelId());
        if (modelConfigVo == null) {
            throw new BaseException("查询不到对应的模型");
        }
        IsfdSceneMapStepModelRef add = MapstructUtils.convert(bo, IsfdSceneMapStepModelRef.class);
        baseMapper.insert(add);
        return Boolean.TRUE;
    }

    @Override
    public Boolean updateByBo(IsfdSceneMapStepModelRefBo bo) {
        IsfdDatabaseModelConfigVo modelConfigVo = iIsfdDatabaseModelConfigService.queryByIdReturnSimpleVo(bo.getModelId());
        if (modelConfigVo == null) {
            throw new BaseException("查询不到对应的模型");
        }
        IsfdSceneMapStepModelRef update = MapstructUtils.convert(bo, IsfdSceneMapStepModelRef.class);
        return baseMapper.updateById(update) > 0;
    }


    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public Boolean deleteByMapStepId(Long mapStepId) {
        baseMapper.delete(new LambdaQueryWrapper<IsfdSceneMapStepModelRef>().eq(IsfdSceneMapStepModelRef::getMapStepId, mapStepId));
        return Boolean.TRUE;
    }

    @Override
    public List<IsfdSceneMapStepModelRefVo> queryListByMapStepId(Long mapStepId, Boolean needStatistics) {
        List<IsfdSceneMapStepModelRefVo> isfdSceneMapStepModelRefsVo = baseMapper.selectVoList(new LambdaQueryWrapper<IsfdSceneMapStepModelRef>().eq(IsfdSceneMapStepModelRef::getMapStepId, mapStepId));
        isfdSceneMapStepModelRefsVo.forEach(vo -> {
            // 当前父模型
            Long modelId = vo.getModelId();
            IsfdDatabaseModelConfigVo currentModelVo = iIsfdDatabaseModelConfigService.queryByIdReturnSimpleVo(modelId);
            vo.setModelName(currentModelVo.getModelName());
            // 所有版本的数据
            List<IsfdDatabaseModelConfigVo> isfdDatabaseModelConfigVos = iIsfdDatabaseModelConfigService.queryListAllVersionList(modelId);

            List<IsfdSceneMapStepModelStatisticsVo> modelList = new ArrayList<>();
            int importCount = 0;
            int serviceCalledCount = 0;
            Set<String> importMethods = new HashSet<>();
            for (IsfdDatabaseModelConfigVo modelConfigVo : isfdDatabaseModelConfigVos) {
                IsfdSceneMapStepModelStatisticsVo statisticsVo = new IsfdSceneMapStepModelStatisticsVo();
                statisticsVo.setModelName(modelConfigVo.getModelName());
                statisticsVo.setModelId(modelConfigVo.getId());
                statisticsVo.setVersionNumber(modelConfigVo.getVersionNumber());
                if (needStatistics) {
                    // 封装导入总数和导入方式
                    IsfdDatabaseDataImportRecordBo recordBo = new IsfdDatabaseDataImportRecordBo();
                    recordBo.setModelId(modelConfigVo.getId());
                    List<IsfdDatabaseDataImportRecordVo> recordVoList = iIsfdDatabaseDataImportRecordService.queryList(recordBo);
                    if (!CollectionUtils.isEmpty(recordVoList)) {
                        for (IsfdDatabaseDataImportRecordVo recordVo : recordVoList) {
                            Integer realCountByCondition = iIsfdDatabaseDataImportRecordService.getRealCountByCondition(recordVo.getId(), modelConfigVo.getTableName());
                            importCount = importCount + realCountByCondition;
                        }
                        //importCount = importCount + recordVoList.stream().mapToInt(IsfdDatabaseDataImportRecordVo::getDataQuantity).sum();
                        importMethods.addAll(recordVoList.stream().map(IsfdDatabaseDataImportRecordVo::getImportMethod).collect(Collectors.toSet()));
                    }
                    // 服务调用次数
                    Integer serviceTimes = isfdServerManagementMapper.getServiceTimesByModelId(modelConfigVo.getId());
                    serviceTimes = serviceTimes == null ? 0 : serviceTimes;
                    serviceCalledCount = serviceCalledCount + serviceTimes;
                }
                modelList.add(statisticsVo);
            }
            vo.setImportCount(importCount);
            vo.setServiceCalledCount(serviceCalledCount);
            vo.setImportMethods(importMethods);
            vo.setModelList(modelList);
        });
        return isfdSceneMapStepModelRefsVo;
    }

    @Override
    public List<BloodRelationshipOuterV2Vo> relationship(Long sceneId, Long systemId, Long databaseTypeId, Long modelId) {
        List<IsfdDatabaseModelConfigVo> allVersionList = iIsfdDatabaseModelConfigService.queryListAllVersionList(modelId);
        List<BloodRelationshipOuterV2Vo> outerList = new ArrayList<>();
        if (CollectionUtils.isEmpty(allVersionList)) {
            return outerList;
        }
        for (IsfdDatabaseModelConfigVo modelConfigVo : allVersionList) {
            BloodRelationshipOuterV2Vo outer = new BloodRelationshipOuterV2Vo();
            outer.setLevel(2);
            outer.setModelId(modelConfigVo.getId());
            outer.setModelName(modelConfigVo.getModelName());
            outer.setVersionNumber(modelConfigVo.getVersionNumber());
            outer.setTableName(modelConfigVo.getTableName());
            IsfdDatabaseDataImportRecordBo recordBo = new IsfdDatabaseDataImportRecordBo();
            recordBo.setModelId(modelConfigVo.getId());
            List<IsfdDatabaseDataImportRecordVo> recordVoList = iIsfdDatabaseDataImportRecordService.queryList(recordBo);
            List<BloodRelationshipInnerV2Vo> innerList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(recordVoList)) {
                for (IsfdDatabaseDataImportRecordVo recordVo : recordVoList) {
                    BloodRelationshipInnerV2Vo inner = new BloodRelationshipInnerV2Vo();
                    String dataImportBy = recordVo.getDataImportBy();
                    if (StringUtils.isNotBlank(dataImportBy)) {
                        String userName = userService.selectUserNameById(Long.valueOf(dataImportBy));
                        inner.setImportUserName(userName);
                        inner.setImportUserId(Long.valueOf(dataImportBy));
                    }
                    inner.setLevel(3);
                    inner.setDataImportTime(recordVo.getDataImportTime());
                    inner.setTableName(recordVo.getTableName());

                    // 封装file
                    List<BloodRelationshipInnerV2Vo.ImportFile> children = new ArrayList<>();
                    BloodRelationshipInnerV2Vo.ImportFile file = new BloodRelationshipInnerV2Vo.ImportFile();
                    file.setLevel(4);
                    file.setImportMethod(recordVo.getImportMethod());
                    file.setRecordId(recordVo.getId());
                    file.setModelId(modelConfigVo.getId());
                    file.setFileName(recordVo.getFileName());
                    Integer realCountByCondition = iIsfdDatabaseDataImportRecordService.getRealCountByCondition(recordVo.getId(), modelConfigVo.getTableName());
                    file.setInventoryCount(Long.valueOf(realCountByCondition));

                    children.add(file);
                    inner.setChildren(children);
                    innerList.add(inner);
                }
            }
            outer.setChildren(innerList);
            outerList.add(outer);
        }
        return outerList;
    }
}
